﻿using Cms.Core.Infrastructure.AuthHelper;
using Cms.Core.Infrastructure.Common;
using Cms.Core.Infrastructure.Extension;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;

namespace Cms.Core.Application.Secutiry.AuthHelper
{  /// <summary>
   /// JWTToken类
   /// </summary>
    public sealed class JwtToken
    {
        /// <summary>
        /// 获取基于JWT的Token
        /// </summary>
        /// <param name="claims">需要在登陆的时候配置</param>
        /// <param name="permissionRequirement">在startup中定义的参数</param>
        /// <returns></returns>
        public static JwtTokenResponse BuildJwtToken(Claim[] claims, PermissionRequirement permissionRequirement)
        {

            DateTime now = DateTime.Now;
        
            DateTime expires = now.Add(permissionRequirement.Expiration);
      
            // 实例化JwtSecurityToken
            SecurityTokenDescriptor descriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(claims),
                Audience = permissionRequirement.Audience,
                Issuer = permissionRequirement.Issuer,
                SigningCredentials = permissionRequirement.SigningCredentials,
                NotBefore = now,
                IssuedAt = now,
                Expires = expires
            };
     
            JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
            SecurityToken token = tokenHandler.CreateToken(descriptor);
            return new JwtTokenResponse
            {
                Success = true,
                Token = tokenHandler.WriteToken(token),
                ExpiresIn = permissionRequirement.Expiration.TotalSeconds,
                TokenType = "Bearer"
            };
        }

        /// <summary>
        /// 解析JWT的Token
        /// </summary>
        /// <param name="jwtStr"></param>
        /// <returns></returns>
        public static dynamic AnalysisJwtToken(string jwtStr)
        {

            var jwtHandler = new JwtSecurityTokenHandler();
            var jwtToken = jwtHandler.ReadJwtToken(jwtStr);
            //ClaimTypes.Name
            jwtToken.Payload.TryGetValue(ClaimTypes.Role, out object role);
            var name = jwtToken.Claims.FirstOrDefault(o => o.Type == ClaimTypes.Name)?.Value;
            dynamic dynamic = new DynamicDictionary();
            dynamic.Uid = jwtToken.Id;
            dynamic.Role = role?.ToString();
            dynamic.Name = name ?? string.Empty;
            return dynamic;
        }

    }



    /// <summary>
    ///
    /// </summary>
    public class JwtTokenResponse
    {
        [JsonProperty("success")]
        public bool Success { get; set; }

        [JsonProperty("token")]
        public string Token { get; set; }

        [JsonProperty("expires_in")]
        public double ExpiresIn { get; set; }

        [JsonProperty("token_type")]
        public string TokenType { get; set; }
    }
}
